package org.cytoscape.myapp.cytoscape_app_v1.internal.metrics.measure;



import org.cytoscape.myapp.cytoscape_app_v1.internal.metrics.domain.UserPositionMapping;
import org.cytoscape.myapp.cytoscape_app_v1.internal.metrics.graph.BasicDirectGraph;
import org.cytoscape.myapp.cytoscape_app_v1.internal.metrics.graph.MyEdge;
import org.cytoscape.myapp.cytoscape_app_v1.internal.metrics.graph.MyNode;

import edu.uci.ics.jung.algorithms.scoring.BetweennessCentrality;
import edu.uci.ics.jung.algorithms.scoring.ClosenessCentrality;
import edu.uci.ics.jung.algorithms.scoring.DegreeScorer;
import edu.uci.ics.jung.algorithms.scoring.EigenvectorCentrality;
import edu.uci.ics.jung.graph.Graph;

public class SocialCentrality {
	
	private UserPositionMapping mapping;

	public SocialCentrality(UserPositionMapping mapping) {
		this.mapping=mapping;
	}

	/**
	 * Return the Social Centrality Vector
	 * @return double[]
	 */
	public double[] getSCVector() {
		double[] sc=new double[this.mapping.getUsers().size()];
		BasicDirectGraph graphConstructor=new BasicDirectGraph();
		Graph<MyNode,MyEdge> g=graphConstructor.constructGraph(this.mapping.getUsers());
		EigenvectorCentrality<MyNode,MyEdge> eScorer=new EigenvectorCentrality<MyNode, MyEdge>(g);
	//	BetweennessCentrality<MyNode,MyEdge> BCranker=new BetweennessCentrality<MyNode,MyEdge>(g);
		DegreeScorer<MyNode> DCranker=new DegreeScorer<MyNode>(g);
		ClosenessCentrality<MyNode, MyEdge> CCranker=new ClosenessCentrality<MyNode, MyEdge>(g);
		double n=g.getVertexCount();
		for (MyNode myNode :graphConstructor.getUsersNodes(this.mapping.getUsers())) {
		//	double BC=BCranker.getVertexScore(myNode)/((n-1)*(n-2)/2);
			double DC=DCranker.getVertexScore(myNode)/(n-1);
			double CC=CCranker.getVertexScore(myNode);
			double EC=eScorer.getVertexScore(myNode);
			double scValue=0.0;
			int cont=0;
//			if(!Double.isNaN(BC)){
//				scValue+=BC;
//				cont++;
//			}
			if(!Double.isNaN(DC)){
				scValue+=DC;
				cont++;
			}
			if(!Double.isNaN(CC)){
				scValue+=CC;
				cont++;
			}
			if(!Double.isNaN(EC)){
				scValue+=EC;
				cont++;
			}
			scValue/=cont;
			
			sc[this.mapping.getPositionByUserId(myNode.getId())]=scValue;
			
		}
		return sc;
	}
}
